using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Text.RegularExpressions;
using Outlook = Microsoft.Office.Interop.Outlook;
using System.IO;
using System.Windows.Forms;

namespace TXLooker.Common.FileFormatCoverters
{
    /// <summary>
    /// 
    /// </summary>
    public class OlFormatConverter : IFormatConverter
    {
        public Microsoft.Office.Interop.Outlook.Application OlApplication
        {
            get { return this.m_OlApplication; }
            internal set
            {
                this.m_OlApplication = value;
            }
        }
        private Microsoft.Office.Interop.Outlook.Application m_OlApplication = null;

        private OlFormatConverter()
        { }
        public OlFormatConverter(Microsoft.Office.Interop.Outlook.Application application)
            : this()
        {
            this.OlApplication = application;
        }

        public string ConvertTo(string sourceString, TextFormatType sourceFormat, TextFormatType targetFormat)
        {
            return ConvertTo(this.OlApplication, sourceString, sourceFormat, targetFormat);
        }

        public static string ConvertTo(Microsoft.Office.Interop.Outlook.Application application, string sourceString, TextFormatType sourceFormat, TextFormatType targetFormat)
        {
            switch (sourceFormat)
            {
                case TextFormatType.Html:
                    switch (targetFormat)
                    {
                        case TextFormatType.PlainText:
                            return HTMLToFormat(application, sourceString, Microsoft.Office.Interop.Outlook.OlSaveAsType.olTXT);
                        case TextFormatType.Rtf:
                            return HTMLToFormat(application, sourceString, Microsoft.Office.Interop.Outlook.OlSaveAsType.olRTF);
                        case TextFormatType.Html:
                        case TextFormatType.Undefined:
                            return sourceString;
                        default:
                            throw new NotImplementedException();
                    }
                case TextFormatType.PlainText:
                    switch (targetFormat)
                    {
                        case TextFormatType.Html:
                            return PlainTextToFormat(application, sourceString, Microsoft.Office.Interop.Outlook.OlSaveAsType.olHTML);
                        case TextFormatType.Rtf:
                            return PlainTextToFormat(application, sourceString, Microsoft.Office.Interop.Outlook.OlSaveAsType.olRTF);
                        case TextFormatType.PlainText:
                        case TextFormatType.Undefined:
                            return sourceString;
                        default:
                            throw new NotImplementedException();
                    }
                case TextFormatType.Rtf:
                    switch (targetFormat)
                    {
                        case TextFormatType.Html:
                            throw new Exception("The method or operation is not implemented.");
                        case TextFormatType.PlainText:
                            return RTFToPlainText(sourceString);
                        case TextFormatType.Rtf:
                        case TextFormatType.Undefined:
                            return sourceString;
                        default:
                            throw new NotImplementedException();
                    }
                default:
                    throw new NotImplementedException();
            }
        }
        private static string HTMLToFormat(Microsoft.Office.Interop.Outlook.Application application, string source, Microsoft.Office.Interop.Outlook.OlSaveAsType type)
        {
            if (type == Microsoft.Office.Interop.Outlook.OlSaveAsType.olHTML)
                return source;

            Microsoft.Office.Interop.Outlook.MailItem item = (Microsoft.Office.Interop.Outlook.MailItem)application.Session.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderJunk).Items.Add(Microsoft.Office.Interop.Outlook.OlItemType.olMailItem);
            item.BodyFormat = Microsoft.Office.Interop.Outlook.OlBodyFormat.olFormatHTML;
            item.HTMLBody = source;
            string path = Path.GetTempFileName();
            item.SaveAs(path, type);
            string result = string.Empty;

            using (StreamReader SR = new StreamReader(path, System.Text.Encoding.GetEncoding("Windows-1251")))
            {
                result = SR.ReadToEnd();
            }
            try
            {
                File.Delete(path);
            }
            catch { }
            item.Delete();
            return result;
        }
        private static string PlainTextToFormat(Microsoft.Office.Interop.Outlook.Application application, string source, Microsoft.Office.Interop.Outlook.OlSaveAsType type)
        {
            if (type == Microsoft.Office.Interop.Outlook.OlSaveAsType.olTXT)
                return source;

            Microsoft.Office.Interop.Outlook.MailItem item = (Microsoft.Office.Interop.Outlook.MailItem)application.Session.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderJunk).Items.Add(Microsoft.Office.Interop.Outlook.OlItemType.olMailItem);
            item.BodyFormat = Microsoft.Office.Interop.Outlook.OlBodyFormat.olFormatRichText;
            item.Body = source;
            string path = Path.GetTempFileName();
            item.SaveAs(path, type);
            string result;
            using (StreamReader SR = new StreamReader(path, System.Text.Encoding.GetEncoding("Windows-1251")))
            {
                result = SR.ReadToEnd();
            }
            try
            {
                File.Delete(path);
            }
            catch { }
            item.Delete();
            return result;
        }
        private static string RTFToPlainText(string source)
        {
            RichTextBoxConverter.Rtf = source;
            return RichTextBoxConverter.Text;
        }

        private static RichTextBox RichTextBoxConverter
        {
            get
            {
                if (m_richTextBox == null)
                {
                    lock (typeof(OlFormatConverter))
                    {
                        if (m_richTextBox == null)
                            m_richTextBox = new RichTextBox();
                    }
                }
                return m_richTextBox;
            }
        }
        private static RichTextBox m_richTextBox = null;

        //public string ConvertHtmlTo(Redemption.RDOSession rdoSession, string sourceString, TextFormatType targetFormat, bool bConvert)
        //{
        //    if (bConvert)
        //        return ConvertHtmlTo(rdoSession, sourceString, targetFormat);
        //    else
        //        return string.Empty;
        //}

        //public static string ConvertHtmlTo(Redemption.RDOSession rdoSession, string sourceString, TextFormatType targetFormat)
        //{
        //    switch (targetFormat)
        //    { 
        //        case TextFormatType.Undefined:
        //        case TextFormatType.Html:
        //            return sourceString;
        //        case TextFormatType.Rtf:
        //            return ConvertHtmlToRtf(rdoSession,sourceString);
        //        case TextFormatType.PlainText:
        //            return ConvertHtmlToPlain(rdoSession,sourceString);
        //        default: throw new NotImplementedException("Not Implement data format");                    
        //    }
        //}

        //private static string ConvertHtmlToPlain(Redemption.RDOSession rdoSession, string sourceString)
        //{
        //    string result = string.Empty;
        //    string path = Path.GetTempFileName();

        //    Redemption.RDOFolder folder = rdoSession.GetDefaultFolder(Redemption.rdoDefaultFolders.olFolderJunk);
        //    Redemption.RDOMail rdoMail = folder.Items.Add(Redemption.rdoItemType.olMailItem);
        //    rdoMail.HTMLBody = sourceString;
        //    rdoMail.SaveAs(path,Redemption.rdoSaveAsType.olTXT);

        //    using (StreamReader streamReader = new StreamReader(path))
        //    {
        //        result = streamReader.ReadToEnd();
        //    }

        //    try
        //    {
        //        File.Delete(path);
        //    }
        //    catch (Exception ex)
        //    {
        //        LogManager.WriteMessageToCustomLog("Error in ConvertHtmlToPlain(Redemption.RDOSession rdoSession, string sourceString) OlFormatConverter.cs " + ex.Message);
        //    }

        //    return result;
        //}

        //private static string ConvertHtmlToRtf(Redemption.RDOSession rdoSession, string sourceString)
        //{
        //    string result = string.Empty;
        //    string path = Path.GetTempFileName();

        //    Redemption.RDOFolder folder = rdoSession.GetDefaultFolder(Redemption.rdoDefaultFolders.olFolderJunk);
        //    Redemption.RDOMail rdoMail = folder.Items.Add(Redemption.rdoItemType.olMailItem);
        //    rdoMail.HTMLBody = sourceString;
        //    rdoMail.SaveAs(path,Redemption.rdoSaveAsType.olRTF);

        //    using (StreamReader streamReader = new StreamReader(path))
        //    {
        //        result = streamReader.ReadToEnd();
        //    }

        //    try
        //    {
        //        File.Delete(path);
        //    }
        //    catch (Exception ex)
        //    {
        //        LogManager.WriteMessageToCustomLog("Error in ConvertHtmlToRtf(Redemption.RDOSession rdoSession, string sourceString) OlFormatConverter.cs " + ex.Message);
        //    }

        //    return result;
        //}

        public string ConvertHtmlTo(string sourceString, TextFormatType targetFormat)
        {
            return ConvertHtmlTo(m_OlApplication,sourceString, targetFormat);
        }
//
        public static string ConvertHtmlTo(Microsoft.Office.Interop.Outlook.Application application, string sourceString, TextFormatType targetFormat)
        {
            switch (targetFormat)
            {
                case TextFormatType.Undefined:
                case TextFormatType.Html:
                    return sourceString;
                case TextFormatType.Rtf:
                    return ConvertHtmlToRtf(application, sourceString);
                case TextFormatType.PlainText:
                    return ConvertHtmlToPlain(application, sourceString);
                default: throw new NotImplementedException("Not Implement data format");
            }   
        }

        private static string ConvertHtmlToPlain(Microsoft.Office.Interop.Outlook.Application application, string sourceString)
        {            
            return Regex.Replace(sourceString, @"(&.*?;)|(<+[^>]+)(>)+", "").Remove(0, 10);
        }

        private static string ConvertHtmlToRtf(Microsoft.Office.Interop.Outlook.Application application, string sourceString)
        {
            string result = string.Empty;
            string path = Path.GetTempFileName();

            Microsoft.Office.Interop.Outlook.MAPIFolder folder = application.Session.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderJunk);
            Microsoft.Office.Interop.Outlook.MailItem mailItem = folder.Items.Add(Microsoft.Office.Interop.Outlook.OlItemType.olMailItem) as Microsoft.Office.Interop.Outlook.MailItem;
            mailItem.HTMLBody = sourceString;
            mailItem.SaveAs(path, Microsoft.Office.Interop.Outlook.OlSaveAsType.olRTF);

            using (StreamReader streamReader = new StreamReader(path))
            {
                result = streamReader.ReadToEnd();
            }

            try
            {
                File.Delete(path);
            }
            catch (Exception ex)
            {
                LogManager.WriteMessageToCustomLog("Error in ConvertHtmlToRtf(Microsoft.Office.Interop.Outlook.Application application, string sourceString) OlFormatConverter.cs " + ex.Message);
            }

            return result;
        }
    }
}
